using System;
using System.Xml;
using DesignByContract;
using Outcoding.GraphGenerator.Entities;
using Outcoding.GraphGenerator.Util.Logging;

namespace Outcoding.GraphGenerator.Composition{
    public class CategoryAxisBuilder : BuilderBase{
        #region Attributes

        //font attributes
        private string fontDecorationAttr = "font-decoration";
        private string fontNameAttr = "font-name";
        private string fontSizeAttr = "font-size";
        private string isSmoothedAttr = "smoothed";
        private string markerSizehAttr = "marker-size";

        #endregion

        private readonly string mNodeName = XmlTagNames.categoryaxis.ToString();

        private XmlNode mNode;

        private string mNodePath{
            get { return "./" + mNodeName; }
        }

        public override void SelectNode(XmlDocument document){
            throw new Exception("The method or operation is not implemented.");
        }

        public override void Compose(){
            throw new Exception("The method or operation is not implemented.");
        }

        public override void Compose(XmlNode node){
            mNode = node.SelectSingleNode(mNodePath);
            try{
                BuildObject(mNode);
            }
            catch (PreconditionException preExc){
                LogManager.Instance.LogWarning("CategoryAxis entity could not be created; process aborted.", preExc);
            }
        }

        public override void AppendToParent(object parent){
            Check.Require(parent is Axes, "Parent object not a valid argument");
            (parent as Axes).CategoryAxis = (CategoryAxis) mProduct;
        }

        private void BuildObject(XmlNode axesXmlNode){
            var categoryAxis = new CategoryAxis();

            if (axesXmlNode.Attributes[markerSizehAttr] != null)
                categoryAxis.DefaultMarkerSize = ParseMarkerSizeAttribute(axesXmlNode);
            if (axesXmlNode.Attributes[isSmoothedAttr] != null)
                categoryAxis.IsSmoothed = ParseIsSmoothedAttribute(axesXmlNode);

            //font attributes
            if (axesXmlNode.Attributes[fontNameAttr] != null)
                categoryAxis.FontName = ParseFontNameAttribute(axesXmlNode);
            if (axesXmlNode.Attributes[fontSizeAttr] != null)
                categoryAxis.FontSize = ParseFontSizeAttribute(axesXmlNode);
            if (axesXmlNode.Attributes[fontDecorationAttr] != null){
                categoryAxis.IsFontBold = ParseIsFontBoldAttribute(axesXmlNode);
                categoryAxis.IsFontItalic = ParseIsFontItalicAttribute(axesXmlNode);
                categoryAxis.IsFontUnderline = ParseIsFontUnderlineAttribute(axesXmlNode);
            }

            mProduct = categoryAxis;
        }

        public int ParseMarkerSizeAttribute(XmlNode axesXmlNode){
            return Int32.Parse(axesXmlNode.Attributes[markerSizehAttr].Value);
        }

        public bool ParseIsSmoothedAttribute(XmlNode axesXmlNode){
            return Boolean.Parse(axesXmlNode.Attributes[isSmoothedAttr].Value);
        }

        private string ParseFontNameAttribute(XmlNode axesXmlNode){
            Check.Require(axesXmlNode.Attributes[fontNameAttr] != null, "font-name attribute not present");
            return axesXmlNode.Attributes[fontNameAttr].Value;
        }

        private int ParseFontSizeAttribute(XmlNode axesXmlNode){
            Check.Require(axesXmlNode.Attributes[fontSizeAttr] != null, "font-size attribute not present");
            return Int32.Parse(axesXmlNode.Attributes[fontSizeAttr].Value);
        }

        private bool ParseIsFontBoldAttribute(XmlNode axesXmlNode){
            Check.Require(axesXmlNode.Attributes[fontDecorationAttr] != null, "font-decoration attribute not present");
            return axesXmlNode.Attributes[fontDecorationAttr].Value.Contains("bold");
        }

        private bool ParseIsFontItalicAttribute(XmlNode axesXmlNode){
            Check.Require(axesXmlNode.Attributes[fontDecorationAttr] != null, "font-decoration attribute not present");
            return axesXmlNode.Attributes[fontDecorationAttr].Value.Contains("italic");
        }

        private bool ParseIsFontUnderlineAttribute(XmlNode axesXmlNode){
            Check.Require(axesXmlNode.Attributes[fontDecorationAttr] != null, "font-decoration attribute not present");
            return axesXmlNode.Attributes[fontDecorationAttr].Value.Contains("underline");
        }
    }
}